package com.yty.demo._7_thread;

/**
 * @author: yangtaoyao
 * @time: 2020/1/13 17:17
 * @description: 同时从3000余额账户转账2000到支付宝和微信
 */
public class Test2 {
    public static void main(String[] args) {
        Acount acount=new Acount(3000);
        Acount acount2=new Acount(3000);

        User u_weixin=new User(acount,2000);
        User u_zhifubao=new User(acount,2000);
//        User u_zhifubao=new User(acount2,2000);


        Thread weixin=new Thread(u_weixin,"微信");
        Thread zhifubao=new Thread(u_zhifubao,"支付宝");

        weixin.start();
        zhifubao.start();

    }
}

class Acount{
    //private static int money=3000;
    private int money;

    public Acount(int money) {
        this.money = money;
    }

    /**
     * 取款
     */
    public void drawing1(int m){
        String name=Thread.currentThread().getName();
        if(m>money){
            System.out.println(String.format("== [%s]操作 账户金额不足：%d", name,money));
        }else{
            System.out.println("== ["+name+"]操作 账户原有金钱："+money);
            System.out.println("== ["+name+"]操作 取款金额："+m);
            money=money-m;
            System.out.println("== ["+name+"]操作 取款后金额："+money);
        }
    }

    //在普通方法上加同步锁，锁的是整个对象，不是某一个方法，不同的对象就是不同的锁；
    //两个线程争夺同一个acount对象锁，同一时刻只有一个线程能获取对象锁。
    public synchronized void drawing2(int m){
        String name=Thread.currentThread().getName();
        if(m>money){
            System.out.println(String.format("== [%s]操作 账户金额不足：%d", name,money));
        }else{
            System.out.println("== ["+name+"]操作 账户原有金钱："+money);
            System.out.println("== ["+name+"]操作 取款金额："+m);
            money=money-m;
            System.out.println("== ["+name+"]操作 取款后金额："+money);
        }
    }

    //同步代码块，对象锁
    public  void drawing3(int m){
        synchronized(this){
            String name=Thread.currentThread().getName();
            if(m>money){
                System.out.println(String.format("== [%s]操作 账户金额不足：%d", name,money));
            }else{
                System.out.println("== ["+name+"]操作 账户原有金钱："+money);
                System.out.println("== ["+name+"]操作 取款金额："+m);
                money=money-m;
                System.out.println("== ["+name+"]操作 取款后金额："+money);
            }
        }
    }

    //同步代码块，类锁
    public   void drawing4(int m){
        synchronized(Acount.class){
            String name=Thread.currentThread().getName();
            if(m>money){
                System.out.println(String.format("== [%s]操作 账户金额不足：%d", name,money));
            }else{
                System.out.println("== ["+name+"]操作 账户原有金钱："+money);
                System.out.println("== ["+name+"]操作 取款金额："+m);
                money=money-m;
                System.out.println("== ["+name+"]操作 取款后金额："+money);
            }
        }
    }
}

class User implements Runnable{
    Acount acount;
    int money;//取款金额
    public User(Acount acount,int money) {
        this.acount = acount;
        this.money=money;
    }

    @Override
    public void run() {
        synchronized (acount){
            //线程通信
            if(Thread.currentThread().getName().equals("微信")){
                try {
                    acount.wait();//放弃资源，当前线程排队等候，使支付宝转账先；
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            acount.drawing1(money);

            if(Thread.currentThread().getName().equals("支付宝")){
                acount.notify();//唤醒正在排队等待同步资源的线程中优先级最高者结束等待；
            }
        }
    }
}
